package com.forcetools.digester;

import java.beans.PropertyDescriptor;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaProperty;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.digester.BeanPropertySetterRule;
import org.apache.commons.digester.Digester;

import com.forcetools.utils.EnumUtils;

public class EnumPropertySetterRule extends BeanPropertySetterRule {

	public EnumPropertySetterRule() {
		super();
	}

	public EnumPropertySetterRule(String propertyName) {
		super(propertyName);
	}

    /**
     * Process the end of this element.
     *
     * @param namespace the namespace URI of the matching element, or an 
     *   empty string if the parser is not namespace aware or the element has
     *   no namespace
     * @param name the local name if the parser is namespace aware, or just 
     *   the element name otherwise
     *
     * @exception NoSuchMethodException if the bean does not
     *  have a writeable property of the specified name
     */
    @Override
	public void end(String namespace, String name) throws Exception {

        String property = propertyName;

        if (property == null) {
            // If we don't have a specific property name,
            // use the element name.
            property = name;
        }

        // Get a reference to the top object
        Object top = digester.peek();
        Digester digester = getDigester();  
        // log some debugging information
        if (digester.getLogger().isDebugEnabled()) {
        	digester.getLogger().debug("[BeanPropertySetterRule]{" + digester.getMatch() +
                    "} Set " + top.getClass().getName() + " property " +
                               property + " with text " + bodyText);
        }

        // Force an exception if the property does not exist
        // (BeanUtils.setProperty() silently returns in this case)
        if (top instanceof DynaBean) {
            DynaProperty desc =
                ((DynaBean) top).getDynaClass().getDynaProperty(property);
            if (desc == null) {
                throw new NoSuchMethodException
                    ("Bean has no property named " + property);
            }
        } else /* this is a standard JavaBean */ {
            PropertyDescriptor desc =
                PropertyUtils.getPropertyDescriptor(top, property);
            if (desc == null) {
                throw new NoSuchMethodException
                    ("Bean has no property named " + property);
            }
        }
        
        // Set the property (with conversion as necessary)
        BeanUtils.setProperty(top, property, EnumUtils.valueOf(name, bodyText));

    }
	
}
